﻿using SYJ.IDAL;
using SYJ.Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using Dapper;
using Dapper.Contrib;
using Dapper.Contrib.Extensions;
using SYJ.Factory;
using System.Reflection;

namespace SYJ.MySqlDAL
{
   public abstract partial class BaseDal<T>:IBaseDal<T> where T :class,new ()
    {
        private IDbConnection _conn;
        public IDbConnection Conn
        {
            get
            {
                if (_conn == null)
                {
                     _conn = DBConnectionFactory.CreateConnection();
                }
                return _conn;   
            }
        }
        #region 基础方法

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
       public int Insert(T t) {
           using (Conn)
           {
               return Convert.ToInt32(Conn.Insert<T>(t));
           }
       }
        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
       public int Insert(List<T> list)
       {
           using (Conn)
           {
               int records = 1;
               using (var trans = Conn.BeginTransaction())
               {
                   try
                   {
                       Conn.Insert( list, trans, 30);
                   }
                   catch (DataException ex)
                   {
                       trans.Rollback();
                       records = 0;
                   }
                   trans.Commit();
               }
               return records ;
           }
       }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
       public bool Update(T t)
       {
           using (Conn) {
               return Conn.Update<T>(t);
           }
       }
        /// <summary>
        /// 批量修改
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
       public bool Update(List<T> list)
       {
           using (Conn)
           {
               bool records = false;
               using (var trans = Conn.BeginTransaction())
               {
                   try
                   {
                       records= Conn.Update(list,trans,30);
                       trans.Commit();
                   }
                   catch (DataException ex)
                   {
                       trans.Rollback();
                   }
                   
               }
               return records;
           }
       }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="t"></param>
        /// <returns></returns>
       public bool Delete(T t)
       {
           using (Conn)
           {
               return Conn.Delete<T>(t);
           }
       }
        /// <summary>
        /// 批量删除
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
       public bool Delete(List<T> list)
       {
            bool result = false;
            using (Conn)
            {
                using (var train = Conn.BeginTransaction())
                {
                    try
                    {
                       result= Conn.Delete(list, train, 30);
                        train.Commit();
                    }
                    catch (DataException ex)
                    {
                        train.Rollback();
                    }
                }
            }
           return result;
       }

        /// <summary>
        /// ID获取实体
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
       public T GetModel(int id)
       {
           using (Conn) {
             return  Conn.Get<T>(id);
           }
       }

        /// <summary>
        /// 获取全部记录
        /// </summary>
        /// <returns></returns>
       public List<T> GetAll()
       {
           using (Conn) {
               string tableName = "";
               Type elementType = typeof(T);
             
               //取类上的自定义特性
               object[] objs = elementType.GetCustomAttributes(typeof(TableAttribute), true);
               foreach (object obj in objs)
               {
                   TableAttribute attr = obj as TableAttribute;
                   if (attr != null)
                   {

                       tableName = attr.Name;//表名只有获取一次
                       break;
                   }
               }
               return Conn.GetAll<T>().AsList();
           }
       }
#endregion


        /// <summary>
        /// 单表分页获取
        /// </summary>
        /// <param name="query"></param>
        /// <returns></returns>
       public List<T> GetPage(QueryModel query,out long count)
       {
           string tabName = GetTableName(typeof(T));
           List<T> list = null;
           using (Conn)
           {
               string sqlCount = string.Format("SELECT Count(*) FROM {0} WHERE 1=1 {1} ", tabName, query.SqlWhere);
               string sql = string.Format("SELECT * FROM {0} WHERE id >= (SELECT id FROM {0} LIMIT {2}, 1) {3} order by {4} {5}  LIMIT {1};", tabName, query.PageSize, query.PageSize * (query.PageIndex - 1), query.SqlWhere,query.OrderName,query.SortOrder);
               if (query.Param == null)
               {
                   list = Conn.Query<T>(sql).AsList();
                   count = Conn.ExecuteScalar<long>(sqlCount);
               }
               else
               {
                   list = Conn.Query<T>(sql, query.Param).AsList();
                   count = Conn.ExecuteScalar<long>(sqlCount, query.Param);
               }
           }
           return list;
       }

       public List<T> Get(string sql)
       {
           using (Conn)
           {
              return Conn.Query<T>(sql).AsList();
           }
       }
       public List<T> Get(string sql,object param)
       {
           using (Conn)
           {
               return Conn.Query<T>(sql,param).AsList();
           }
       }
       public T GetModel(string sql)
       {
           using (Conn)
           {
               return Conn.Get<T>(sql);
           }
       }
       public T GetModel(string sql, object param)
       {
           using (Conn)
           {
               return Conn.QueryFirst<T>(sql,param);
           }
       }
        #region 帮助
       /// <summary>
       /// 获取T类型的Table特性
       /// </summary>
       /// <param name="elementType"></param>
       /// <returns></returns>
       public string GetTableName(Type elementType)
       {
              string tableName = "";
             
               //取类上的自定义特性
               object[] objs = elementType.GetCustomAttributes(typeof(TableAttribute), true);
               foreach (object obj in objs)
               {
                   TableAttribute attr = obj as TableAttribute;
                   if (attr != null)
                   {

                       tableName = attr.Name;//表名只有获取一次
                       break;
                   }
               }
               return tableName;
        }
      
        #endregion

    }
}
